package com.googlecode.mapperdao

import com.googlecode.mapperdao.jdbc.Setup

import org.scalatest.FunSuite
import org.scalatest.matchers.ShouldMatchers
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

/**
 * @author: kostas.kougios
 *          Date: 09/04/13
 */
@RunWith(classOf[JUnitRunner])
class UseCaseGraphOfEntitiesSuite extends FunSuite with ShouldMatchers
{

	import UseCaseGraphOfEntitiesSuite._

	if (Setup.database == "postgresql") {
		val (jdbc, mapperDao, queryDao) = Setup.setupMapperDao(TypeRegistry(ProductEntity, AttributeEntity))

		test("insert") {
			createTables()
			val p1 = Product(
				"p1", Set(
					Attribute("a1", "v1",
						Set(
							Log("attr1 first insert"))
					)),
				Set(
					Log("prod1 first insert")
				)
			)
			val i1 = mapperDao.insert(ProductEntity, p1)
			i1 should be(p1)

			mapperDao.select(ProductEntity, i1.id).get should be(i1)
		}

		def createTables() {
			Setup.dropAllTables(jdbc)
			val queries = Setup.queries(this, jdbc)
			queries.update("ddl")
		}
	}
}

object UseCaseGraphOfEntitiesSuite
{

	case class Product(name: String, attributes: Set[Attribute], logs: Set[Log])

	case class Attribute(name: String, value: String, logs: Set[Log])

	case class Log(change: String)

	object ProductEntity extends Entity[Int, SurrogateIntId, Product]
	{
		val id = key("id") autogenerated (_.id)
		val name = column("name") to (_.name)
		val attributes = manytomany(AttributeEntity) to (_.attributes)
		val logs = manytomany(LogEntity) to (_.logs)

		def constructor(implicit m: ValuesMap) = new Product(name, attributes, logs) with Stored
		{
			val id: Int = ProductEntity.id
		}
	}

	object AttributeEntity extends Entity[Int, SurrogateIntId, Attribute]
	{
		val id = key("id") autogenerated (_.id)
		val name = column("name") to (_.name)
		val value = column("value") to (_.value)
		val logs = manytomany(LogEntity) to (_.logs)

		def constructor(implicit m: ValuesMap) = new Attribute(name, value, logs) with Stored
		{
			val id: Int = AttributeEntity.id
		}
	}

	object LogEntity extends Entity[Int, SurrogateIntId, Log]
	{
		val id = key("id") autogenerated (_.id)
		val change = column("change") to (_.change)

		def constructor(implicit m: ValuesMap) = new Log(change) with Stored
		{
			val id: Int = LogEntity.id
		}
	}

}